package cn.edu.nchu.fragmentdemo.myComponents.overLays;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import cn.edu.nchu.fragmentdemo.MainActivity;
import cn.edu.nchu.fragmentdemo.bean.Route;
import cn.edu.nchu.fragmentdemo.entity.MyRouteEntity;
import cn.edu.nchu.fragmentdemo.myComponents.NewCircleComponents.NewCirclePopupMenu_WayPoint;
import cn.edu.nchu.fragmentdemo.myComponents.components.MyArrowMarkerClass;
import cn.edu.nchu.fragmentdemo.myComponents.components.MyMarkerClass;
import cn.edu.nchu.fragmentdemo.utils.CaculateOfTwoGeoPoint;
import cn.edu.nchu.fragmentdemo.utils.MarkDrawable;
import cn.edu.nchu.fragmentdemo.utils.CommenUtils;
import cn.edu.nchu.fragmentdemo.utils.ImageUtil;
import cn.edu.nchu.fragmentdemo.utils.MyOverlayManager;

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.Polyline;
import org.osmdroid.views.overlay.infowindow.InfoWindow;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

/**
 * 航线层  用于绘制航线
 */
public class RouteLay extends Overlay {
    private MainActivity mainActivity;
    private final Context context;
    private final MapView mapView;
    //点存进线中
    private Polyline polyline;
    //经纬度点集
    private ArrayList<GeoPoint> geoPoints;
    //Maker标记集合
    private ArrayList<MyMarkerClass> markers;
    //maker对应的点击弹窗
    private ArrayList<InfoWindow> infoWindows;
    private MyArrowMarkerClass myArrowMarkerClass;
    //通过commenUtils读取drawable中的图标文件
    private CommenUtils commenUtils;
    private String whickMarkerUK;

    //数据库用的
    private Route route;
    private int route_no;
    private RouteLay thisRouteLay;
    private MyRouteEntity myRouteEntity;

    //
    InfoWindow infoWindowCP, infoWindowIP, infoWindowEP;
    TextView textViewCP, textViewIP, textViewEP;
    LinearLayout linearLayoutCP, linearLayoutIP, linearLayoutEP;

    public RouteLay(String makerUk) {
        this.whickMarkerUK = makerUk;
        thisRouteLay = this;
        mainActivity = (MainActivity) MainActivity.getActivity();
        context = mainActivity.getApplicationContext();
        mapView = mainActivity.getMap();
        route = new Route();
        geoPoints = new ArrayList<>();
        commenUtils = new CommenUtils();
        markers = new ArrayList<>();
        infoWindows = new ArrayList<>();
        myArrowMarkerClass = new MyArrowMarkerClass(mapView);
        myArrowMarkerClass.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker, MapView mapView) {
                return false;
            }
        });
        myRouteEntity = new MyRouteEntity();
        //这里装入，并没有什么具体值
        myRouteEntity.setEntity(route);
        myRouteEntity.setId(MyOverlayManager.getUid());
        myRouteEntity.setTag("POLYLINE");
        myRouteEntity.setDbTag("POLYLINE");
        initRoute();
        setCustomIWIP();
        setCustomIWEP();
        setCustomIWCP();
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e, MapView mapView) {
        //onSingleTapUp  单击后抬起
        Projection projection = mapView.getProjection();
        GeoPoint geo = (GeoPoint) projection.fromPixels((int) e.getX(), (int) e.getY());
        //获取点击后的位置点后添加进点集合中
        addPoint(geo);
        //如果点的数量大于2，展示两点间的距离
        if (geoPoints.size() >= 2) {
            showDistance(geoPoints.get(geoPoints.size() - 2), geoPoints.get(geoPoints.size() - 1));
        }
        return super.onSingleTapUp(e, mapView);
    }

    private void initRoute() {
        //设置航线的样式
        polyline = new Polyline();
        polyline.setPoints(geoPoints);
        polyline.setWidth(7f);
        polyline.setColor(Color.GREEN);
        polyline.setGeodesic(true);
        polyline.setSubDescription(Polyline.class.getCanonicalName());
        mapView.getOverlays().add(polyline);
    }

    /**
     * 点击一下地图，路线上加一个点
     *
     * @param geoPoint
     */
    public void addPoint(GeoPoint geoPoint) {
        polyline.addPoint(geoPoint);
        geoPoints.add(geoPoint);
        final MyMarkerClass marker = new MyMarkerClass(mapView);
        marker.setPosition(geoPoint);
        marker.setDraggable(true);
        markers.add(marker);
        marker.setSubDescription(String.valueOf(markers.size()));
        String word = String.valueOf(markers.size());
        marker.setId(word);
        //获取航点图片
        Bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), commenUtils.getResource("routepoint_18"));
        //在航点中心显示序号
        mBitmap = ImageUtil.drawTextToCenter(context, mBitmap, word, 10, Color.rgb(191, 191, 191));
        MarkDrawable drawable = new MarkDrawable(context.getResources(), mBitmap);
        marker.setIcon(drawable);

        //回调方法
        marker.setDataChangeListener(new MyMarkerClass.DataChangeListener() {
            @Override
            public void setData(Object result) throws SQLException {
                if (result.toString().equals("change")) {
//                    int index = Integer.parseInt(marker.getSubDescription());
                    int index = 0;
                    for (int i = 0; i < markers.size(); i++) {
                        if (markers.get(i).equals(marker)) {
                            index = i;
                            break;
                        }
                    }
                    geoPoints.set(index, marker.getPosition());
                    //重绘路线，点，距离
                    redrawRout();
                    //重绘title和箭头
                    if (marker.getId().equals("60")) {
                        setCPTitle((MyMarkerClass) marker);
                    }
                    if (marker.getId().equals("70")) {
                        setIPTitle((MyMarkerClass) marker);
                    }
                    if (marker.getId().equals("78")) {
                        setEPTitle((MyMarkerClass) marker);
                        setEPArrawPos();
                    }
                }
            }
        });
        marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker, MapView mapView) {
                //appDataManger看不懂？？
                //do something
                //mainActivity.showToast("marker is clicked!");
//                if (AppDataManager.isAllLock)
//                    return true;
//                if (AppDataManager.getInstance().getInfoCurrentFragmentName().equals("TaskFragment")) {
//                    TaskFragment taskFragment = (TaskFragment) AppDataManager.getInstance().getInfoCurrentFragment();
//                    if (!taskFragment.getmTaskIbtnPlay().isEnabled()) {
//                        return true;
//                    }
//                }
                //显示环形菜单
                mapView.setExpectedCenter(marker.getPosition());
                NewCirclePopupMenu_WayPoint newCirclePopupMenu_wayPoint = new NewCirclePopupMenu_WayPoint(context, (MyMarkerClass) marker, thisRouteLay);
                newCirclePopupMenu_wayPoint.showPopupMenu();
                return false;
            }
        });

        marker.setOnMarkerDragListener(new Marker.OnMarkerDragListener() {
            @Override
            public void onMarkerDrag(Marker marker) {
            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                //int index = Integer.parseInt(marker.getSubDescription());
                int index = 0;
                for (int i = 0; i < markers.size(); i++) {
                    if (markers.get(i).equals(marker)) {
                        index = i;
                        break;
                    }
                }
                geoPoints.set(index, marker.getPosition());
                //重绘路线，点，距离
                redrawRout();
                //重绘title和箭头
                if (marker.getId().equals("60")) {
                    setCPTitle((MyMarkerClass) marker);
                }
                if (marker.getId().equals("70")) {
                    setIPTitle((MyMarkerClass) marker);
                }
                if (marker.getId().equals("78")) {
                    setEPTitle((MyMarkerClass) marker);
                    setEPArrawPos();
                }
                //发送消息，通知改变
                try {
                    sendMessage("change");
                    if (marker.getId().equals("70")) {
                        sendMessage("change70");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onMarkerDragStart(Marker marker) {
            }
        });
        mapView.getOverlays().add(marker);
    }

    /**
     * 在路线上中加一个点
     *
     * @param geoPoint
     */
    private void addPointOnRoute(GeoPoint geoPoint, int i) {
        polyline.getPoints().add(i, geoPoint);
        geoPoints.add(i, geoPoint);

        final MyMarkerClass marker = new MyMarkerClass(mapView);
        marker.setPosition(geoPoint);
        marker.setDraggable(true);
        markers.add(i, marker);

        marker.setSubDescription(String.valueOf(markers.size() - 1));
        String word = String.valueOf(markers.size() - 1 + 60);
        marker.setId(word);
        Bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), commenUtils.getResource("routpoint_18"));
        mBitmap = ImageUtil.drawTextToCenter(context, mBitmap, word, 10, Color.BLACK);
        MarkDrawable drawable = new MarkDrawable(context.getResources(), mBitmap);
        marker.setIcon(drawable);
        //回调方法
        marker.setDataChangeListener(new MyMarkerClass.DataChangeListener() {
            @Override
            public void setData(Object result) throws SQLException {
                if (result.toString().equals("change")) {
                    //int index = Integer.parseInt(marker.getSubDescription());
                    int index = 0;
                    for (int i = 0; i < markers.size(); i++) {
                        if (markers.get(i).equals(marker)) {
                            index = i;
                            break;
                        }
                    }
                    geoPoints.set(index, marker.getPosition());
                    //重绘路线，点，距离
                    redrawRout();
                    //重绘title和箭头
                    if (marker.getId().equals("60")) {
                        setCPTitle((MyMarkerClass) marker);
                    }
                    if (marker.getId().equals("70")) {
                        setIPTitle((MyMarkerClass) marker);
                    }
                    if (marker.getId().equals("78")) {
                        setEPTitle((MyMarkerClass) marker);
                        setEPArrawPos();
                    }
                }
            }
        });
        marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker, MapView mapView) {
                //do something
//                //mainActivity.showToast("marker is clicked!");
//                if (AppDataManager.isAllLock)
//                    return true;
//                if (AppDataManager.getInstance().getInfoCurrentFragmentName().equals("TaskFragment")) {
//                    TaskFragment taskFragment = (TaskFragment) AppDataManager.getInstance().getInfoCurrentFragment();
//                    if (!taskFragment.getmTaskIbtnPlay().isEnabled()) {
//                        return true;
//                    }
//                }
//                mapView.setExpectedCenter(marker.getPosition());
//                NewCirclePopupMenu_WayPoint newCirclePopupMenu_wayPoint = new NewCirclePopupMenu_WayPoint(context, (MyMarkerClass) marker, thisRouteLay);
//                newCirclePopupMenu_wayPoint.showPopupMenu();
                return false;
            }
        });
        marker.setOnMarkerDragListener(new Marker.OnMarkerDragListener() {
            @Override
            public void onMarkerDrag(Marker marker) {
            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
//                if (AppDataManager.isAllLock)
//                    return;
                //int index = Integer.parseInt(marker.getSubDescription());
                int index = 0;
                for (int i = 0; i < markers.size(); i++) {
                    if (markers.get(i).equals(marker)) {
                        index = i;
                        break;
                    }
                }
                geoPoints.set(index, marker.getPosition());
                //重绘路线，点，距离
                redrawRout();
                //重绘title和箭头
                if (marker.getId().equals("60")) {
                    setCPTitle((MyMarkerClass) marker);
                }
                if (marker.getId().equals("70")) {
                    setIPTitle((MyMarkerClass) marker);
                }
                if (marker.getId().equals("78")) {
                    setEPTitle((MyMarkerClass) marker);
                    setEPArrawPos();
                }
                //发送消息，通知改变
                try {
                    sendMessage("change");
                    if (marker.getId().equals("70")) {
                        sendMessage("change70");
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onMarkerDragStart(Marker marker) {

            }
        });
        mapView.getOverlays().add(marker);
    }

    public void showDistance(GeoPoint geoPoint1, GeoPoint geoPoint2) {
        double len = 0;
        Polyline polyline = new Polyline();
        polyline.addPoint(geoPoint1);
        polyline.addPoint(geoPoint2);
        len = polyline.getDistance();
        //小数点后两位
        len = (double) Math.round(len * 100) / 100;
        //设置infowindow
        LinearLayout linearLayout = new LinearLayout(context);
        TextView textView1 = new TextView(context);
        textView1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        textView1.setText("" + len + "米");
        textView1.setBackgroundColor(0xccffffff);
        textView1.setTextColor(Color.BLACK);
        textView1.setTextSize(10);
        textView1.setPadding(10, 10, 10, 10);
        linearLayout.addView(textView1);
        InfoWindow infoWindow = new InfoWindow(linearLayout, mapView) {
            @Override
            public void onOpen(Object item) {
            }

            @Override
            public void onClose() {
            }
        };
        //不知道最后两个参数是干啥的
        infoWindow.open(polyline, CaculateOfTwoGeoPoint.getMid(geoPoint1, geoPoint2), 1, 1);
        infoWindows.add(infoWindow);
    }

    private void redrawRout() {
        //删掉原来的线和marker
        mapView.getOverlays().remove(polyline);
        mapView.getOverlays().removeAll(markers);
        for (InfoWindow infoWindow : infoWindows) {
            infoWindow.close();
        }
        infoWindows.clear();
        //重绘路线
        initRoute();
        //重绘标记点
        mapView.getOverlays().addAll(markers);
        //重绘距离
        if (geoPoints.size() >= 2) {
            for (int i = 0; i < geoPoints.size() - 1; i++) {
                showDistance(geoPoints.get(i), geoPoints.get(i + 1));
            }
        }
        mapView.invalidate();
    }



    /**
     * 删除路线上的一个点
     *
     * @param marker
     */

    public void deletePoint(MyMarkerClass marker) {
        //需要删除array中的marker和point，然后重绘
        geoPoints.remove(markers.indexOf(marker));
        markers.remove(marker);
        mapView.getOverlays().remove(marker);
        redrawRout();
        //重绘title和箭头
        if (marker.getId().equals("60")) {
            hideCPTitle();
        }
        if (marker.getId().equals("70")) {
            hideIPTitle();
        }
        if (marker.getId().equals("78")) {
            hideEPTitle();
            mapView.getOverlays().remove(myArrowMarkerClass);
        }
        mapView.invalidate();
    }

    /* 删除绘制的所有点 */
    public void romoveAllinMap() {
        mapView.getOverlays().removeAll(markers);
        for (InfoWindow infoWindow : infoWindows) {
            infoWindow.close();
        }
        hideCPTitle();
        hideIPTitle();
        hideEPTitle();
        mapView.getOverlays().remove(polyline);
        mapView.getOverlays().remove(myArrowMarkerClass);
        mapView.invalidate();
    }

    public void reverseRouteInMap() {
        ArrayList<GeoPoint> tempPoints = new ArrayList<>();
        Collections.reverse(geoPoints);
        tempPoints.addAll(geoPoints);
        //删掉原来的线和marker
        mapView.getOverlays().remove(polyline);
        mapView.getOverlays().removeAll(markers);
        for (InfoWindow infoWindow : infoWindows) {
            infoWindow.close();
        }
        infoWindows.clear();
        markers.clear();
        geoPoints.clear();
        initRoute();
        for( GeoPoint geoPoint: tempPoints) {
            addPoint(geoPoint);
        }
        mapView.invalidate();
    }

    public void setVisible(boolean b) {
        polyline.setEnabled(b);
        for (MyMarkerClass myMarkerClass : markers) {
            myMarkerClass.setVisible(b);
        }
        for (InfoWindow infoWindow : infoWindows) {
            if (b == true) {
                infoWindow.getView().setVisibility(View.VISIBLE);
            }
            if (b == false) {
                infoWindow.getView().setVisibility(View.GONE);
            }
        }
        if (myArrowMarkerClass != null) {
            myArrowMarkerClass.setVisible(b);
        }
        mapView.invalidate();
    }

    public void setEPArrawPos() {
        for (int i = 0; i < markers.size(); i++) {
            if (markers.get(i).getId().equals("78")) {//是EP点
                myArrowMarkerClass.setPosition(geoPoints.get(i));
            }
        }
        mapView.invalidate();
    }

    public void setCustomIWCP() {
        linearLayoutCP = new LinearLayout(context);
        infoWindowCP = new InfoWindow(linearLayoutCP, mapView) {
            @Override
            public void onOpen(Object item) {
            }

            @Override
            public void onClose() {
            }
        };
        textViewCP = new TextView(context);
        textViewCP.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        textViewCP.setBackgroundColor(Color.parseColor("#00000000"));
        textViewCP.setTextColor(Color.BLUE);
        textViewCP.setText("CP");
        textViewCP.setTextSize(14);
        textViewCP.setPadding(0, 0, 0, 0);
        linearLayoutCP.addView(textViewCP);
    }

    public void setCPTitle(MyMarkerClass myMarkerClass) {
        infoWindowCP.setRelatedObject(myMarkerClass);
        infoWindowCP.open(myMarkerClass, myMarkerClass.getPosition(), 0, 46);
    }

    public void hideCPTitle() {
        infoWindowCP.close();
    }

    public void setCustomIWIP() {
        linearLayoutIP = new LinearLayout(context);
        infoWindowIP = new InfoWindow(linearLayoutIP, mapView) {
            @Override
            public void onOpen(Object item) {
            }

            @Override
            public void onClose() {
            }
        };
        textViewIP = new TextView(context);
        textViewIP.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        textViewIP.setBackgroundColor(Color.parseColor("#00000000"));
        textViewIP.setTextColor(Color.GREEN);
        textViewIP.setText("IP");
        textViewIP.setTextSize(14);
        textViewIP.setPadding(0, 0, 0, 0);
        linearLayoutIP.addView(textViewIP);
    }

    public void setIPTitle(MyMarkerClass myMarkerClass) {
        infoWindowIP.setRelatedObject(myMarkerClass);
        infoWindowIP.open(myMarkerClass, myMarkerClass.getPosition(), 0, 46);
    }

    public void hideIPTitle() {
        infoWindowIP.close();
    }

    public void setCustomIWEP() {
        linearLayoutEP = new LinearLayout(context);
        infoWindowEP = new InfoWindow(linearLayoutEP, mapView) {
            @Override
            public void onOpen(Object item) {
            }

            @Override
            public void onClose() {
            }
        };
        textViewEP = new TextView(context);
        textViewEP.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        textViewEP.setBackgroundColor(Color.parseColor("#00000000"));
        textViewEP.setTextColor(Color.YELLOW);
        textViewEP.setText("EP");
        textViewEP.setTextSize(14);
        textViewEP.setPadding(0, 0, 0, 0);
        linearLayoutEP.addView(textViewEP);
    }

    public void hideEPTitle() {
        infoWindowEP.close();
    }

    public void setEPTitle(MyMarkerClass myMarkerClass) {
        infoWindowEP.close();
        infoWindowEP.setRelatedObject(myMarkerClass);
        infoWindowEP.open(myMarkerClass, myMarkerClass.getPosition(), 0, 46);
    }

    //getter and setter

    public Polyline getPolyline() {
        return polyline;
    }

    public void setPolyline(Polyline polyline) {
        this.polyline = polyline;
    }

    public ArrayList<GeoPoint> getGeoPoints() {
        return geoPoints;
    }

    public void setGeoPoints(ArrayList<GeoPoint> geoPoints) {
        this.geoPoints = geoPoints;
    }

    public ArrayList<MyMarkerClass> getMarkers() {
        return markers;
    }

    public void setMarkers(ArrayList<MyMarkerClass> markers) {
        this.markers = markers;
    }

    public ArrayList<InfoWindow> getInfoWindows() {
        return infoWindows;
    }

    public void setInfoWindows(ArrayList<InfoWindow> infoWindows) {
        this.infoWindows = infoWindows;
    }


    //新加的：callback
    private DataChangeListener dataChangeListener;// 消息处理完成的监听器

    public void removeThis() {
        myRouteEntity.setOverlay(this);
        myRouteEntity.setGeoPoints(geoPoints);
        mapView.getOverlays().remove(this);
        //添加到图层，但先不存数据库
        MyOverlayManager.getInstance().addToOverlayManager(myRouteEntity);
        //如果marker点为0；直接删除
        if (markers.size() == 0) {
            try {
                MyOverlayManager.getInstance().deletPolylineOverlay(myRouteEntity);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public String getWhickMarkerUK() {
        return whickMarkerUK;
    }

    /**
     * 数据获取完成的监听器
     */
    public interface DataChangeListener {
        void setData(Object result) throws SQLException;
    }

    //
    public void sendMessage(Object message) throws SQLException {
        if (dataChangeListener != null) {
            dataChangeListener.setData(message);// 设置监听器，进行后续操作
        }
    }

    public DataChangeListener getDataChangeListener() {
        return dataChangeListener;
    }

    public void setDataChangeListener(DataChangeListener dataChangeListener) {
        this.dataChangeListener = dataChangeListener;
    }
}
